#include <iostream>
#include <stdio.h>
#include <stdlib.h>

#include "utils.02.h"
#include "timings.01.h"
#include "fjf_nn2_sse_cor_n.01.h"
#include "fjf_nn2_sse_cor_th_n.01.h"
#include "hermit4_sse.barrier.h"


int main(){
	
	#define KB 1000

  	uint N = 10000;
	uint ncore = 1;
	uint align = 512;
	double dt=0.125;
	double period=0.125;
	
	dj01::Hermit4_SSE_TH hermit4;
	

		uint _N=N+1;
		
 		char *testp; 
		double *test  = (double*)new_align(64*KB, 8, align, testp);
	
		char *mp, *x0p,*x1p,*x2p, *v0p,*v1p,*v2p, *potp;
	
		double *m  = (double*)new_align(_N, 8, align, mp);
	
		double *x0 = (double*)new_align(_N, 8, align, x0p);
		double *x1 = (double*)new_align(_N, 8, align, x1p);
		double *x2 = (double*)new_align(_N, 8, align, x2p);
	
		double *v0 = (double*)new_align(_N, 8, align, v0p);	
		double *v1 = (double*)new_align(_N, 8, align, v1p);
 		double *v2 = (double*)new_align(_N, 8, align, v2p);

		double eps2=SQR(1e-4);
	
		for (int i=0; i<N; i++)	{
			x0[i]=1-2*(double)rand()/RAND_MAX;
			x1[i]=1-2*(double)rand()/RAND_MAX;
			x2[i]=1-2*(double)rand()/RAND_MAX;
		}

		for (int i=0; i<N; i++)	{
			v0[i]=1-2*(double)rand()/RAND_MAX;
			v1[i]=1-2*(double)rand()/RAND_MAX;
			v2[i]=1-2*(double)rand()/RAND_MAX;
		}
	
		for (int i=0; i<N; i++)	m[i]=1.0/N; m[N]=0;
	
		
		double dummy;
		FILE *file = fopen("data/data.inp", "r");
		fscanf( file, "%le\n%u\n%le\n", &dummy, &N, &dummy);
		for (int i=0; i<N; i++)
		fscanf( file, "%le %le %le %le %le %le %le %le\n",
		&dummy, &m[i], &x0[i],&x1[i],&x2[i], &v0[i],&v1[i],&v2[i]);
		fclose(file);
		/**/

		double t=0;
		Timer tr;
		
		do {
			
		tr.set();
		hermit4.integrate(N, m, x0,x1,x2, v0,v1,v2, eps2, ncore, dt, pow(2,-23));
		tr.get();
		t+=dt;
		
		printf("\n");
		printf("NB Time = %g sec\n", t);
		printf("WC Time = %g sec\n", tr.sin);
		printf("nn2 = %.1f %%\n", 100*(double)hermit4.s_nn2ij/(hermit4.s_nnij+hermit4.s_nn2ij));
		printf("n_act Avr = %g\n",hermit4.s_n/(double)hermit4.n_bts);
 		printf("Eff. Speed = %g Gflops\n", 60*(hermit4.s_n*N/tr.sin/1e9));
		printf("Real Speed = %g Gflops\n", double( (18+19+2+22)*hermit4.s_nnij + (21+19+3+25)*hermit4.s_nn2ij ) /tr.sin/1e9 );
		printf("Real Speed = %g Gflops (NVidia)\n", double( (19+2+22)*hermit4.s_nnij + (22+3+25)*hermit4.s_nn2ij ) /tr.sin/1e9 );
		printf("DE1 = %g\n", hermit4.E.dtot1);
		printf("DE = %g\n", hermit4.E.dtot);
		
		
		
		} while (t<period);
		
		
		
		
		delete [] mp;
		delete [] x0p;
		delete [] x1p;
		delete [] x2p;
		delete [] v0p;
		delete [] v1p;
		delete [] v2p;
		delete [] potp;
		delete [] testp;
		
		//printf("\n");
	//}
	return 0;
}

